查看原文
其他

Rust漏洞查找分析工具——Rudra


本文来自佐治亚理工学院,研究Rust的安全漏洞。本文提出寻找Rust漏洞的工具——Rudra。该工具可以发现Rust包中 41.4% 的 bug(自2016年起),且相当高效(能在十小时内分析绝大多数 Rust 包)。该项目已在Github上开源,开发者可以修改Rudra工具,对自己写的Rust程序以及第三方程序进行安全分析

1

Introduction

Rust作为一种安全语言,以其安全内存模型受到社区欢迎。虽然 Rust 通过提供所有权机制和借还机制保证了内存安全,但是这些安全规则在底层编程的时候显得过于严格,比如不能通过裸指针访问某一片内存等。于是 Rust 提供了 unsafe 关键字和 unsafe 块,允许开发者自行保证代码块的安全。如下图,根据作者对 crate.io 的统计分析,有超过70%的 Rust 包中都含有 Unsafe 代码。

因为unsafe代码没有内存安全的保证,所以一旦在unsafe代码中存在漏洞,将会影响到safe代码。作者分析了 Rust 中已知的内存 bug,并分为了三类:

  1. Panic Safety:Rust在处理panic的时候,会展开栈,并且回收其中的变量。如果变量v的类型是T,但是v不属于T类型的安全变量(即变量v无法安全的创建,例如非UTF-8编码的字符串),那么在遇到panic并回收该变量的时候,将导致内存漏洞;

  2. Higher-order Safety Invariant:一些高阶不变式在Rust中没有得到保证。除了Rust编译器提供的安全不变式外,不做任何假设。例如,即便用户提供的比较器不考虑全序(total order),Rust中的sort函数也不能触发任何未定义的行为。如果Rust代码违背这些高级不变式,将导致Rust代码漏洞;

  3. Propagating Send/Sync in Generic Types:没有将send和sync的类型传递到泛化类型中。对于该类型错误的定义是,如果一个泛化类型中的内部类型没有给出正确的send/sync的限制,那么该泛化变量可能存在send/sync不相符的bug。



2

Design




整体来看,Rudra 接受一个 Rust 包作为输入、并产生两个检查器的报告。在作者的实现中,Rudra 被实现为一个 Rust 编译器的驱动。在 Rust 编译器完成类型检查之后,它会使用编译器内部的数据进行分析。

Rudra 在实现分析算法时使用两个 Rust 编译器 IR:HIR 和 MIR。第一种 IR 是从 AST 生成的高级 IR (HIR)。HIR 包含目标程序中每个定义的 ID(例如函数、trait 实现)及其关联的表达式。HIR 在其表达式中保留了原始代码结构。第二种 IR 是通过降低 HIR 生成的中级 IR (MIR)。MIR 侧重于语义信息。它具有比 HIR 更简单且对分析器更友好的结构,但它也缺少 Rudra 需要的一些重要的非语义信息,例如 Unsafe 代码块的位置,这些信息在类型检查后被删除。 Rudra 不能使用后期阶段的 IR(例如 LLVM IR),LLVM IR已经缺少了泛型的原始信息。

Rudra使用两个算法对 unsafe 代码进行检查:

  1. Unsafe Dataflow Checker(UD):不安全数据流检查器会检查处理生命周期旁路值的函数中的数据流。它使用粗粒度的污点跟踪来识别 panic safety bugs 和 higher-order invariant bugs 分析算法检查是否存在数据流从生命周期到可能会 panic 的函数或以可能 panic 的函数为高阶参数的函数。

  2. Send/Sync Variance Checker (SV):根据相关的 API 签名为每个代数数据类型 (ADT) 估计必要的最小 Send/Sync 边界值。如果 ADT 不包含必要的边界,它会报告发送/同步可能未正确实现。


在测试方面,作者将 crates.io 上的 43k 个包全部进行了测试。除去无法编译的、不产生 rust 代码的包,在剩下的 33k 的包中,Rudra 发现了 264 个新bugs,包含了 76 个CVE。


本文来源:COMPASS Lab

END

往期推荐


TDSC 2022 | 为安全联邦学习建立互信的多混洗框架
隐私信息检索拓展应用
2023年度腾讯犀牛鸟精英人才计划——隐私保护相关课题
VFL:针对纵向联邦学习的全面综述性文章
欢迎投稿邮箱:pet@openmpc.com参与更多讨论,请添加小编微信加入交流群

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存